package com.gmldd.dao.impl;

import com.gmldd.dao.BaseDao;

import com.gmldd.util.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by gmldd on 2016/7/31.
 */
public class BaseDaoImpl<T> implements BaseDao<T>{

    private Connection con;

    private Class<T> clazz;

    private String tableName;

    private Field[] fields;

    BaseDaoImpl(){

        // 得到泛型<T>
        ParameterizedType pt = (ParameterizedType) this.getClass()
                .getGenericSuperclass();

        // 得到泛型T的真实类型,比如CardDao<Card>,得到的是Card
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0];

        this.tableName = clazz.getSimpleName().toUpperCase();

        init();

    }

    public void init(){

        T t = null;

        try {
            t = (T) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 获得实体类的所有字段(包括私有字段)
        fields = t.getClass().getDeclaredFields();
        // 存放实体类字段对应的值
        for (int i = 0; i < fields.length; i++) {
            // 强制访问,不设置无法改变私有字段的值
            fields[i].setAccessible(true);
        }


    }

    public void add(T entity){

        String insert = "insert into "+tableName;

        String[] paramName = new String[fields.length];

        Object[] paramValue = new Object[fields.length];

        StringBuilder sb = new StringBuilder();

        sb.append(insert);
        sb.append("(");

        try {
            for (int i = 0; i < fields.length; i++) {
                paramName[i] = fields[i].getName();
                paramValue[i] = fields[i].get(entity);
                if(i==0) {
                    sb.append(paramName[i]);
                }else{
                    sb.append(","+paramName[i]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        sb.append(") values(");
        for (int i = 0; i < paramValue.length; i++) {
            if(i==0) {
                sb.append("?");
            }else{
                sb.append(",?");
            }

        }

        sb.append(")");

        System.out.println(sb.toString());

        try {
            //1. 连接
            con = JdbcUtils.getConnection();
            //2. 工具类
            QueryRunner qr = new QueryRunner();

            qr.update(con,sb.toString(),paramValue);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }

    }

    public void delete(T entity){

    }

    public void delete(int id){

        String sql = "delete from "+tableName +" where id = ?";
        try {
            //1. 连接
            con = JdbcUtils.getConnection();
            //2. 工具类
            QueryRunner qr = new QueryRunner();

            //3. 查询
            qr.update(con, sql,id);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }

    }

    public void delete(String id){

    }

    public void update(T entity){

        String update = "update "+tableName;

        String[] paramName = new String[fields.length];

        Object[] paramValue = new Object[fields.length];

        StringBuilder sb = new StringBuilder();

        sb.append(update);
        sb.append(" set ");

        try {
            for (int i = 0; i < fields.length; i++) {
                if(fields[i].getName().equals("id")){
                    paramName[fields.length-1] = fields[i].getName();
                    paramValue[fields.length-1] = fields[i].get(entity);
                }else{
                    if(i>0){
                        if(paramName[i-1]==null){
                            paramName[i-1] = fields[i].getName();
                            paramValue[i-1] = fields[i].get(entity);
                            sb.append(paramName[i-1]+" = "+"?,");
                        }else{
                            paramName[i] = fields[i].getName();
                            paramValue[i] = fields[i].get(entity);
                            sb.append(paramName[i]+" = "+"?,");
                        }
                    }else{
                        paramName[i] = fields[i].getName();
                        paramValue[i] = fields[i].get(entity);
                        sb.append(paramName[i]+" = "+"?,");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        sb.setCharAt(sb.length()-1,' ');
        sb.append("where id = ?");

        System.out.println(sb.toString());

        try {
            //1. 连接
            con = JdbcUtils.getConnection();
            //2. 工具类
            QueryRunner qr = new QueryRunner();

            qr.update(con,sb.toString(),paramValue);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }

    }

    public T getById(int id){

        String sql = "select * from "+tableName +" where id = ?";
        try {
            //1. 连接
            con = JdbcUtils.getConnection();
            //2. 工具类
            QueryRunner qr = new QueryRunner();

            //3. 查询
            return (T)qr.query(con, sql, new BeanHandler(clazz),id);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }

    public T get(T entity){
        return null;
    }


    public List<T> getIds(int[] ids){
        return null;
    }


    public List<String> getIds(String[] ids){
        return null;
    }

    public List<T> getAll(){

        String sql = "select * from "+tableName;
        try {
            //1. 连接
            con = JdbcUtils.getConnection();
            //2. 工具类
            QueryRunner qr = new QueryRunner();
            //3. 查询
            return (List<T>) qr.query(con, sql, new BeanListHandler(clazz));

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }


    public void executeSql(String sql){

    }

    public String getTableName(){
        return tableName;
    }

    public String[] getColumnName(){
        return null;
    }

    public List<T> getPage(int pageSize, int pageNum){
        return null;
    }

}
